﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Swoosh.Contracts.MediaPlayerLib;
using System.Xml.Serialization;
using Swoosh.Utilities.TraceLogger;
using System.IO;
using System.Net;
using System.Xml;

namespace Swoosh.MediaPlayers.VlcOldHttp
{
    public class Player : IPlaybackDevice
    {
        private string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        private string _StorageName;
        public string StorageName
        {
            get { return _StorageName; }
            set { _StorageName = value; }
        }

        public Storage Storage
        {
            get
            {
                return SwooshConfig.CurrentConfig.StorageList.Where(s => s.Name == StorageName).FirstOrDefault();
            }
        }

        private Playlist _Playlist;
        public Playlist Playlist
        {
            get { return _Playlist; }
        }

        private VlcOldHttpConfig _Config;

        public Player()
        {
            _Name = "";
            _StorageName = "";
            _Playlist = new Playlist();
        }


        public bool LoadConfiguration(string Configuration)
        {
            bool ret = false;

            XmlSerializer xmlSer = new XmlSerializer(typeof(VlcOldHttpConfig));

            try
            {
                _Config = (VlcOldHttpConfig)xmlSer.Deserialize(new StringReader(Configuration));

                ret = true;
            }
            catch (Exception ex)
            {
                Logger.Log(LogLevels.Error, Name + " - unable to load configuration", ex);
                _Config = new VlcOldHttpConfig();
            }
            return ret;
        }


        public bool Start()
        {
            return true;
        }

        public bool Stop()
        {
            return true;
        }


        public bool ClearPlaylist()
        {
            string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml?command=pl_empty";

            WebClient web_client = new WebClient();

            Byte[] page_in_bytes = web_client.DownloadData(requesturi);

            return true;
        }

        public bool QueuePlaylistItem(PlaylistItem Item)
        {
            if (!Item.IsCurrent)
            {

                string filename = Item.File.Replace("\\", "//").Replace("//", "\\\\");

                string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml?command=in_enqueue&input=" + filename;

                WebClient web_client = new WebClient();

                Byte[] page_in_bytes = web_client.DownloadData(requesturi);

                string page_source = Encoding.UTF8.GetString(page_in_bytes);
            }
            return true;
        }

        public bool PlayPlaylistItem(PlaylistItem Item)
        {
            string filename = Item.File.Replace("\\", "//").Replace("//", "\\\\");

            string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml?command=in_play&input=" + filename;



            WebClient web_client = new WebClient();

            Byte[] page_in_bytes = web_client.DownloadData(requesturi);
            if (Item.SeekTime>0)
                SeekInCurrentPlayback(Item);

            return true;
        }


        private bool SeekInCurrentPlayback(PlaylistItem Item)
        {
            int s = Item.SeekTime;

            string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml?command=seek&val=" + s; 
            WebClient web_client = new WebClient();
            System.Threading.Thread.Sleep(200); //some videos have a long loading time - and then seeking doesn't work without short sleeping
            Byte[] page_in_bytes = web_client.DownloadData(requesturi);

            return true;
        }

        public Playlist ReadPlayList()
        {
            string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/playlist.xml";

            WebClient web_client = new WebClient();

            Byte[] page_in_bytes = web_client.DownloadData(requesturi);

            string page_source = Encoding.UTF8.GetString(page_in_bytes);

            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(page_source);

            _Playlist = new Playlist();
            
            int position = 0;
            foreach (XmlNode node in xmldoc.GetElementsByTagName("node"))
            {
                string name = node.Attributes["name"].Value;
                if (name.Equals("Wiedergabeliste") || name.Equals("Playlist"))
                {

                    foreach (XmlNode leaf in node.ChildNodes)
                    {
                        string file = Uri.UnescapeDataString(leaf.Attributes["uri"].Value.ToString());
                        if (file.Contains("///"))
                        {
                            file = file.Remove(0, 8);
                        }
                        else
                        {
                            file = file.Remove(0, 5);
                        }
                        file = file.Replace("/", "\\");
                        string label = leaf.Attributes["name"].Value.ToString();
                        bool current = false;
                        try
                        {
                            current = (leaf.Attributes["current"].Value.ToString() == "current") ? true : false;
                        }
                        catch
                        {
                            current = false;
                        }
                        PlaylistItem pli = new PlaylistItem() { File = file, Label = label, Position = position, IsCurrent = current };
                        if (current)
                        {
                            _Playlist.Current = pli;
                        }
                        _Playlist.Items.Add(pli);

                        Logger.Log(LogLevels.Debug, "Pos: " + position + " File: " + file);

                        position++;
                    }
                }
            }

            if (_Playlist.Current != null)
            {
                requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml";
                web_client = new WebClient();
                page_in_bytes = web_client.DownloadData(requesturi);
                page_source = Encoding.UTF8.GetString(page_in_bytes);
                xmldoc = new XmlDocument();
                xmldoc.LoadXml(page_source);

                foreach (XmlNode node in xmldoc.GetElementsByTagName("time"))
                {
                    _Playlist.Current.SeekTime = Convert.ToInt32(node.InnerText.ToString());
                }
            }

            return _Playlist;
        }


        public bool StopPlayback()
        {
            string requesturi = "http://" + _Config.ServerName + ":" + _Config.ServerPort + "/requests/status.xml?command=pl_stop";

            WebClient web_client = new WebClient();

            Byte[] page_in_bytes = web_client.DownloadData(requesturi);

            return true;
        }

    }
}
